// blockchain.go (已修正)
package main

import (
	"crypto/rand"
	"encoding/hex"
	"math/big"
	"strconv" // <--- 导入 strconv
)

// BlockchainVerifier 模拟区块链验证者
type BlockchainVerifier struct {
	params *SystemParams
}

// NewBlockchainVerifier 创建一个新的验证者
func NewBlockchainVerifier(params *SystemParams) *BlockchainVerifier {
	return &BlockchainVerifier{params: params}
}

// GetCurrentState 模拟获取当前区块链状态 (如最新区块哈希)
func (bv *BlockchainVerifier) GetCurrentState() string {
	b := make([]byte, 16)
	rand.Read(b)
	return hex.EncodeToString(b)
}

// VerifyProof 验证CSP提交的证明
func (bv *BlockchainVerifier) VerifyProof(proof *Proof, pk *PublicKey, metadata *FileMetadata) bool {
	// 1. 重构挑战
	challengeIndices := make(map[int]int)
	for i := 0; i < proof.C; i++ {
		idx := bv.params.F(proof.Tau, i, metadata.NumBlocks)
		challengeIndices[idx]++
	}

	// 2. 计算 γ = h(T)
	gamma := bv.params.h(proof.T)

	// 3. 计算等式右边: e( (Π H(Wj)^vj)^γ * u^μ, v)
	H_prod := bv.params.Pairing.NewG1().Set1()
	for j, count := range challengeIndices {
		// *** FIX: Use strconv.Itoa for correct string conversion ***
		vjData := []byte(proof.Tau + strconv.Itoa(j))
		vj := bv.params.Pairing.NewZr().SetFromHash(vjData)

		// *** FIX: Use strconv.Itoa for correct string conversion ***
		wjData := []byte(metadata.Name + strconv.Itoa(j))
		h_wj := bv.params.H(wjData)

		h_wj_vj := bv.params.Pairing.NewG1().PowZn(h_wj, vj)
		if count > 1 {
			countZr := bv.params.Pairing.NewZr().SetBig(big.NewInt(int64(count)))
			h_wj_vj.PowZn(h_wj_vj, countZr)
		}
		H_prod.Mul(H_prod, h_wj_vj)
	}

	// (Π H(Wj)^vj)^γ
	H_prod_gamma := bv.params.Pairing.NewG1().PowZn(H_prod, gamma)

	// u^μ
	u_mu := bv.params.Pairing.NewG1().PowZn(bv.params.U, proof.Mu)

	// (Π H(Wj)^vj)^γ * u^μ
	rhs_base := bv.params.Pairing.NewG1().Mul(H_prod_gamma, u_mu)

	// e(rhs_base, v)
	rhs := bv.params.Pairing.NewGT().Pair(rhs_base, pk.V)

	// 4. 计算等式左边: T * e(σ^γ, g)

	// σ^γ
	sigma_gamma := bv.params.Pairing.NewG1().PowZn(proof.Sigma, gamma)

	// e(σ^γ, g)
	e_sigma_g := bv.params.Pairing.NewGT().Pair(sigma_gamma, bv.params.G)

	// T * e(σ^γ, g)
	lhs := bv.params.Pairing.NewGT().Mul(proof.T, e_sigma_g)

	// 5. 比较
	return lhs.Equals(rhs)
}
